﻿
/**
 * 台风 对象类【统一管理】 
 */
var Typhoon = function (viewer, options) {
    this.viewer = viewer;
    this.options = options;
    this._visible = false;

    this.positionScratch = new Cesium.Cartesian3();

    this.init();
};


Typhoon.prototype.init = function () {
    if (!this._visible) return;

    var that = this;

    this.dataSource = new Cesium.CustomDataSource();
    this.viewer.dataSources.add(this.dataSource);

    var startTime;
    var stopTime;
    var property = new Cesium.SampledPositionProperty();

    var positions = [];

    //添加路径点
    var arr = this.options.points;
    for (var i = 0, len = arr.length; i < len; i++) {
        var item = arr[i];

        var position = Cesium.Cartesian3.fromDegrees(item.lng, item.lat);
        positions.push(position);

        var juliaDate = Cesium.JulianDate.fromDate(new Date(item.time));
        property.addSample(juliaDate, position);

        item._position = position;
        item._time = juliaDate;


        if (i == 0)
            startTime = juliaDate;
        else if (i == len - 1)
            stopTime = juliaDate;

        this.addEntitPoint(item, position);
    }
    this.positions = positions;
    this.startTime = startTime;
    this.stopTime = stopTime;


    if (this.viewer.timeline)
        this.viewer.timeline.zoomTo(startTime, stopTime);

    this.lineEntity = this.dataSource.entities.add({
        availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
            start: startTime,
            stop: stopTime
        })]),
        position: property,
        orientation: new Cesium.VelocityOrientationProperty(property),
        path: {
            resolution: 1,
            leadTime: 0,
            trailTime: 99999999,
            material: new Cesium.Color.fromCssColorString("#ff0000").withAlpha(0.9),
            width: 2,
        }
    });

};

//实时运行事件
Typhoon.prototype.preRender_eventHandler = function (e) {
    var time = this.viewer.clock.currentTime;
    //当前点
    var position = Cesium.Property.getValueOrUndefined(this.lineEntity.position, time, this.positionScratch);
    if (position) {
        var item = this.getLastPoints();

        this.showItem({
            _lastPosition: item._position,
            _position: position,
            radius7: item.radius7,
            radius10: item.radius10
        });
    }
}

//获取已完成的点
Typhoon.prototype.getLastPoints = function () {
    var idx = 0;
    var arr = this.options.points;
    for (var i = 0, length = arr.length; i < length; i++) {
        if (Cesium.JulianDate.compare(arr[i]._time, this.viewer.clock.currentTime) > 0) {
            idx = i - 1;
            break;
        }
    }
    return this.options.points[idx];
}


//添加途径的圆点
Typhoon.prototype.addEntitPoint = function (item, position) {
    var that = this;

    var inthtml = '<table style="width: 220px;"><tr>\
            <th scope="col" colspan="4"  style="text-align:center;font-size:15px;">'+ this.options.tfid + ' 台风动态信息</th></tr>\
            <tr><td >中文名</td><td >' + this.options.name + '</td></tr>\
            <tr><td >经度</td><td >' + item.lng + ' 度</td></tr>\
            <tr><td >纬度</td><td >' + item.lat + ' 度</td></tr>\
            <tr><td >中心气压</td><td >' + item.pressure + ' 百帕</td></tr>\
            <tr><td >7级风圈半径</td><td >' + item.radius7 + ' 千米</td></tr>\
            <tr><td >10级风圈半径</td><td >' + item.radius10 + ' 千米</td></tr>\
            <tr><td >最大风速</td><td >' + item.speed + ' 米/秒</td></tr>\
            <tr><td >移动方向</td><td >' + item.movedirection + '</td></tr>\
            <tr><td >移动速度</td><td >' + item.movespeed + ' 米/秒</td></tr>\
            <tr><td >当前时间</td><td >' + item.time + '</td></tr>\
        </table>';


    var entity = this.dataSource.entities.add({
        position: position,
        point: {
            show: new Cesium.CallbackProperty(function (time) {
                return Cesium.JulianDate.compare(entity.data._time, that.viewer.clock.currentTime) <= 0;
            }, false),
            color: new Cesium.Color.fromCssColorString("#ffff00"),
            pixelSize: 10,
            outlineColor: new Cesium.Color.fromCssColorString("#ffffff"),
            outlineWidth: 2,
            heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
            scaleByDistance: new Cesium.NearFarScalar(1.5e2, 1.0, 8.0e6, 0.4),
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
        tooltip: inthtml,
        data: item,
        click: function (entity) {
            that.viewer.clock.currentTime = entity.data._time;
        }
    });
    return entity;
}


//实时更新点
Typhoon.prototype.showItem = function (item) {
    var that = this;
    this._item_position = item._position;

    //台风中心点 图片gif
    if (!this.circle7Entity) {
        this.dataSource.entities.add({
            position: new Cesium.CallbackProperty(function (time) {
                return that._item_position;
            }, false),
            billboard: {//图片，后期可以换位model小模型
                scale: 0.2,
                image: 'img/marker/tf.gif',
                // image: new Cesium.GifImageProperty({
                //     url: 'img/marker/tf.gif'
                // }),
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                scaleByDistance: new Cesium.NearFarScalar(10000, 1, 1000000, 0.6),
                disableDepthTestDistance: Number.POSITIVE_INFINITY,
            },
            label: {//文字
                text: this.options.name,
                font: 'normal small-caps normal 17px 楷体',
                style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                fillColor: Cesium.Color.AZURE,
                outlineColor: Cesium.Color.BLACK,
                outlineWidth: 2,
                horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                pixelOffset: new Cesium.Cartesian2(0, -40),   //偏移量  
                heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
                distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0.0, 2000000)
            },
        });
    }



    //7级风圈
    this._radius7 = Number(item.radius7 || 0) * 1000;
    if (!this.circle7Entity) {
        this.circle7Entity = this.dataSource.entities.add({
            name: '7级风圈',
            show: new Cesium.CallbackProperty(function (time) {
                return that._radius7 > 0;
            }, false),
            position: new Cesium.CallbackProperty(function (time) {
                return that._item_position;
            }, false),
            ellipse: {
                semiMinorAxis: new Cesium.CallbackProperty(function (time) {
                    return that._radius7;
                }, false),
                semiMajorAxis: new Cesium.CallbackProperty(function (time) {
                    return that._radius7;
                }, false),
                material: Cesium.Color.RED.withAlpha(0.4),
                zIndex: 20
            }
        });
    }



    //10级风圈
    this._radius10 = Number(item.radius10 || 0) * 1000;
    if (!this.circle10Entity) {
        this.circle10Entity = this.dataSource.entities.add({
            name: '10级风圈',
            show: new Cesium.CallbackProperty(function (time) {
                return that._radius10 > 0;
            }, false),
            position: new Cesium.CallbackProperty(function (time) {
                return that._item_position;
            }, false),
            ellipse: {
                semiMinorAxis: new Cesium.CallbackProperty(function (time) {
                    return that._radius10;
                }, false),
                semiMajorAxis: new Cesium.CallbackProperty(function (time) {
                    return that._radius10;
                }, false),
                material: Cesium.Color.YELLOW.withAlpha(0.2),
                zIndex: 10
            }
        });
    }




    //求方位角
    var point1 = mars3d.point.formatPosition(item._lastPosition);
    var point2 = mars3d.point.formatPosition(item._position);
    var pt1 = turf.point([point1.x, point1.y, point1.z]);
    var pt2 = turf.point([point2.x, point2.y, point2.z]);
    var bearing = Math.round(turf.rhumbBearing(pt1, pt2));

    //求参考点
    var newpoint = turf.destination(pt2, 150, bearing, { units: 'kilometers' });
    this._target_position = Cesium.Cartesian3.fromDegrees(newpoint.geometry.coordinates[0], newpoint.geometry.coordinates[1]);

    //下一步影像区域半径 虚线展示
    if (!this.dashedLineEntity) {
        this.dashedLineEntity = this.dataSource.entities.add({
            name: '虚线',
            polyline: {
                positions: new Cesium.CallbackProperty(function (time) {
                    return [that._item_position, that._target_position];
                }, false),
                width: 3,
                material: new Cesium.PolylineDashMaterialProperty({
                    color: Cesium.Color.YELLOW
                })
            }
        });
    }

    //求半弧 
    var angle = 180;//张角
    var arc = turf.lineArc(newpoint, 50, bearing - angle / 2, bearing + angle / 2);

    var lonlats = [point2.x, point2.y];
    for (var i = 0; i < arc.geometry.coordinates.length; i++) {
        var item = arc.geometry.coordinates[i];
        lonlats.push(Number(item[0]));
        lonlats.push(Number(item[1]));
    }
    this.circlularHierarchy = Cesium.Cartesian3.fromDegreesArray(lonlats);

    //下一步影像区域 圆锥+扇形区域
    if (!this.circlularEntity) {
        this.circlularEntity = this.dataSource.entities.add({
            polygon: {
                hierarchy: new Cesium.CallbackProperty(function (time) {
                    return new Cesium.PolygonHierarchy(that.circlularHierarchy);
                }, false),
                material: Cesium.Color.YELLOW.withAlpha(0.3)
            }
        });
    }



}




//修改显示、隐藏状态
Typhoon.prototype.setVisible = function (val) {
    if (this._visible === val) return;

    this._visible = val;

    if (this.dataSource == null)
        this.init();

    if (this._visible) {
        //设置时间
        viewer.clock.startTime = this.startTime.clone();
        viewer.clock.stopTime = this.stopTime.clone();
        viewer.clock.currentTime = this.startTime.clone();
        viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;

        if (!this.viewer.dataSources.contains(this.dataSource))
            this.viewer.dataSources.add(this.dataSource);

        if (this.positions.length > 2) {
            var viewRect = Cesium.Rectangle.fromCartesianArray(this.positions);
            var lonDiff = viewRect.east - viewRect.west;
            var latDiff = viewRect.north - viewRect.south;
            viewRect.east += lonDiff;
            viewRect.west -= latDiff;
            viewRect.north += lonDiff;
            viewRect.south -= latDiff;
            this.viewer.camera.flyTo({ destination: viewRect });
        }
        else {
            this.viewer.camera.flyTo({
                destination: mars3d.point.setPositionsHeight(this.positions[0], 1000),
                orientation: { heading: 0, pitch: Cesium.Math.toRadians(-90), roll: 0 }
            });
        }


        this.viewer.scene.preRender.addEventListener(this.preRender_eventHandler, this);
    } else {
        if (this.viewer.dataSources.contains(this.dataSource))
            this.viewer.dataSources.remove(this.dataSource);


        this.viewer.scene.preRender.removeEventListener(this.preRender_eventHandler, this);
    }
};


//释放
Typhoon.prototype.destroy = function () {
    if (this.dataSource == null) return;

    this.dataSource.entities.removeAll()
    if (this.viewer.dataSources.contains(this.dataSource))
        this.viewer.dataSources.remove(this.dataSource);
};
